package com.siecom.module;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;

import com.TcFingerClient.TcFingerClientApi;
import com.example.dmtprotocollib.DmtProtocol;
import com.example.dmtprotocollib.DmtSPIProcess;
import com.eyecool.fp.util.FpCoder;
import com.eyecool.fp.util.SerialPortUtil;
import com.fingerUsb.Callback;
import com.fingerUsb.FingerResult;
import com.fingerUsb.OnConnectListener;
import com.fingerUsb.USBComm;
import com.siecom.algorithm.aes.KeyInfoUtil;
import com.siecom.algorithm.des.AlgorithmUtil;
import com.siecom.algorithm.sm.SM2keyPair;
import com.siecom.algorithm.sm.SMUtil;
import com.siecom.algorithm.util.Arrays;
import com.siecom.constconfig.ConstDefine;
import com.siecom.constconfig.ErrorDefine;
import com.siecom.hostservice.MainActivity;
import com.siecom.tool.ByteTool;
import com.siecom.tool.LogUtil;
import com.siecom.tool.MyToast;
import com.siecom.tool.Timer;
//import com.techshino.fp.util.FpCoder;
//import com.techshino.fp.util.FpImage;
//import com.techshino.fp.util.SerialPortUtil;
import com.siecom.zhq.hostservice.BuildConfig;
import com.techshinogongjian.fp.client.TcFingerClient;
import com.techshinogongjian.fp.util.FpConfig;
import com.techshinogongjian.fp.util.FpConst;
import com.techshinogongjian.fp.util.USBUtil;
import com.wellcom.finger.FpDriverV22;
import com.zz.finger.FingerDevice;

import org.json.JSONException;
import org.json.JSONObject;
import org.zz.jni.zzFingerAlg;
import org.zz.mxhidfingerdriver.MXFingerDriver;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import static android.content.Context.MODE_PRIVATE;
import static com.siecom.constconfig.ConstDefine.KEY_3DES;
import static com.siecom.constconfig.ConstDefine.KEY_NOENCRYPTION;
import static com.siecom.constconfig.ConstDefine.KEY_SM;


/**
 * Created by zhq on 2016/6/24.
 */
public class DeviceInterface {

    public static Bitmap fingerImage = null;


    public final static String NO_ENCRYPTION = "10";
    public final static String THREE_DES_MODE = "30";
    public final static String DES_MODE = "20";
    public final static String DES_MODE_MAIN = "70";
    public final static String SM4_MODE = "80";
    public final static String SM4_MODE_MAIN = "90";

    public final static String TAG = "DeviceInterface";

    public static IDCardModule identityModule = IDCardModule.getInstance();
    public static CipherKeyBoardModule keyBoardModule = CipherKeyBoardModule.getInstance();
    public static FinancialModule financialModule = FinancialModule.getInstance();
    public static TesoFingerprintModule tesoFingerPrintModule = TesoFingerprintModule.getInstance();

    public static final String sBmpFile = Environment.getExternalStorageDirectory() + "/finger_wl.bmp";

    public static CallBackHandler handler = new CallBackHandler();


    /**
     * 模块独立线程池所有操作通过线程池保证先入先出
     */
    private static ExecutorService wellThreadPool = Executors.newFixedThreadPool(1);

    private static ExecutorService finanThreadPool = Executors.newFixedThreadPool(1);

    private static ExecutorService keyThreadPool = Executors.newFixedThreadPool(1);

    private static ExecutorService fingerThreadPool = Executors.newFixedThreadPool(1);

    private static ExecutorService idThreadPool = Executors.newFixedThreadPool(1);

    private static ExecutorService DmtThreadPool = Executors.newFixedThreadPool(1);

    private static DmtSPIProcess dmtTest = new DmtSPIProcess();


    private static USBComm mUsbUtil;
    private static TcFingerClient mClient;
    private static MXFingerDriver zzClient;


    /**
     * 各模块均为单线程，会先终结当前线程再起
     */

    public static FingerPrintRunnable fingerPrintRunnable = null;
    public static IdentityRunnable identityRunnable = null;
    public static KeyBoardRunnable keyBoardRunnable = null;
    private static FinancialRunnable financialRunnable = null;

    public static KeyInputRunnable keyInputRunnable = null;

    private final static int START = 0;
    private final static int SUCCESS = 1;
    private final static int ERROR = 2;
    private final static int COMPLETED = 3;

    private static volatile boolean INIT_SIGN = false;

    private static byte[] cipherData = new byte[102400];
    private static int retryTimes = 0;

    public static int isEncrypted = 0;
    SerialPortUtil mSerialPortUtil;
    private static String mPortPath = "/dev/ttyMT1";
    private static int mBaudrate = 9600;

    private TcFingerClient mTcFingerClient;
    private Context mContext;
    private static byte[] mTemplate;
    public static KeyInfoUtil keyInfoUtil = new KeyInfoUtil(MainActivity.context);
    public static TcFingerClientApi mTcFingerClientApi;

    public static enum Result {

        START, SUCCEED, ERROR, COMPLETED

    }


    public static void InitFinger(){
        if(Build.MODEL.equals("A108Plus")) TcFingerClientApi.gpio_control(100, 1);
        if(!TcFingerClientApi.gpio_read(124)){
            TcFingerClientApi.gpio_control(124, 1);
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


        mTcFingerClientApi = new TcFingerClientApi(MainActivity.context);
        mTcFingerClientApi.DLL_OpenDevice(mPortPath, mBaudrate);
        LogUtil.e(TAG,"mPortPath == " + mPortPath + " ---- mBaudrate == " + mBaudrate);
        mTcFingerClientApi.clear();

    }

    public static int light = 0;

    public static void lightOff() {
//        rkGpioControlNative.ControlGpio(rkGpioControlNative.RK30_PIN0_PA2, 0);
//        rkGpioControlNative.ControlGpio(rkGpioControlNative.ID_LIGHT, 0);
//        rkGpioControlNative.ControlGpio(rkGpioControlNative.MSR_LIGHT, 0);
//        rkGpioControlNative.ControlGpio(rkGpioControlNative.IC_LIGHT, 0);
//        rkGpioControlNative.ControlGpio(rkGpioControlNative.FINGERPRINT_LIGHT, 0);
        MainActivity.getmSys().DLL_SysLedControl((byte) 0,(byte)0);//键盘
        MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);//指纹
        MainActivity.getmSys().DLL_SysLedControl((byte) 2,(byte)0);//IC
        MainActivity.getmSys().DLL_SysLedControl((byte) 3,(byte)0);//磁条卡
        MainActivity.getmSys().DLL_SysLedControl((byte) 4,(byte)0);//蓝牙
        MainActivity.getmSys().DLL_SysLedControl((byte) 5,(byte)0);//身份证

    }
    /**
     *
     * @param voiceType 声音类型：
     * 0：请输入密码
     * 1：请再次输入密码
     * 2：密码错误，请重新输入密码
     * 3：请放置身份证
     * 4：请放置IC卡
     * 5：请插入IC卡
     * 6：请刷磁条卡
     * 7：请签字
     * 8：请录入指纹
     * 9：请重新录入指纹
     * a：操作成功
     * @return
     */
    public static int makeVoice(int voiceType){
        MainActivity.soundPoolPlayByUser(voiceType + 1);
        return 0;
    }

    public static void makeBeep(int times,int dlyTimeMs){
//        MainActivity.getmSys().DLL_SysBeef((byte) 1,new byte[]{(byte) dlyTimeMs});
        for (int i = 0; i < times; i++) {
            MainActivity.getmSys().DLL_SysBeep();
            try {
                if (i != times -1)
                    Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param ledNum IC 灯 0；磁条卡灯 1；身份证灯 2；指纹灯 3
     * @param onOff 亮灭：亮 1；灭 2
     */
    public static void lightCtrl(int ledNum,int onOff) {
        if (ledNum >=0 && ledNum <= 3){
            if (onOff != 1) onOff = 0 ;
            if (ledNum == 0)
                MainActivity.getmSys().DLL_SysLedControl((byte) 2,(byte)onOff);//IC
            if (ledNum == 1)
                MainActivity.getmSys().DLL_SysLedControl((byte) 3,(byte)onOff);//Msr
            if (ledNum == 2)
                MainActivity.getmSys().DLL_SysLedControl((byte) 5,(byte)onOff);//ID
            if (ledNum == 3)
                MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)onOff);//Finger
            return;
        }
        if (light == 0) {
            light = 1;
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.RK30_PIN0_PA2, 1);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.ID_LIGHT, 1);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.MSR_LIGHT, 1);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.IC_LIGHT, 1);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.FINGERPRINT_LIGHT, 1);
            MainActivity.getmSys().DLL_SysLedControl((byte) 0,(byte)1);//键盘
            MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)1);//指纹
            MainActivity.getmSys().DLL_SysLedControl((byte) 2,(byte)1);//IC
            MainActivity.getmSys().DLL_SysLedControl((byte) 3,(byte)1);//磁条卡
            MainActivity.getmSys().DLL_SysLedControl((byte) 4,(byte)1);//蓝牙
            MainActivity.getmSys().DLL_SysLedControl((byte) 5,(byte)1);//身份证

        } else {
            light = 0;
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.RK30_PIN0_PA2, 0);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.ID_LIGHT, 0);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.MSR_LIGHT, 0);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.IC_LIGHT, 0);
//            rkGpioControlNative.ControlGpio(rkGpioControlNative.FINGERPRINT_LIGHT, 0);
            MainActivity.getmSys().DLL_SysLedControl((byte) 0,(byte)0);//键盘
            MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);//指纹
            MainActivity.getmSys().DLL_SysLedControl((byte) 2,(byte)0);//IC
            MainActivity.getmSys().DLL_SysLedControl((byte) 3,(byte)0);//磁条卡
            MainActivity.getmSys().DLL_SysLedControl((byte) 4,(byte)0);//蓝牙
            MainActivity.getmSys().DLL_SysLedControl((byte) 5,(byte)0);//身份证
        }

    }

    /**
     *
     */
//    public static void sendScreenOnOffBroadCast(){
//        Intent intent = new Intent();
//        intent.setAction("android.intent.action.SCREEN_OFF");
//        MainActivity.context.sendBroadcast(intent);
//        try {
//            Thread.sleep(10);
//            intent.setAction("android.intent.action.SCREEN_ON");
//            MainActivity.context.sendBroadcast(intent);
//
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }

    public static void closeSignature() {
        if (INIT_SIGN) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    int res = dmtTest.closeDMTSignDM();
                    Log.e("closeDMTSignDM", res + "");
                }
            };
            DmtThreadPool.submit(runnable);
        }
    }

    public static void clearSignature() {
        if (INIT_SIGN) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    int res = dmtTest.clearDMTSignDM();
                    Log.e("clearDMTSignDM", res + "");
                }
            };
            DmtThreadPool.submit(runnable);
        }

    }

    public static void startSignature() {
        if (INIT_SIGN) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    int res = dmtTest.startDMTSignDM();
                    Log.e("startDMTSignDM", res + "");
                }
            };
            DmtThreadPool.submit(runnable);
        }
    }

    public static void endSignature(DeviceCallback callback, boolean isOnMain) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                try {
                    if (INIT_SIGN) {
                        int res = dmtTest.endDMTSignDM();
                        Log.e("endDMTSignDM", res + "");
                        SystemClock.sleep(200);
                        int[] length = new int[1];
                        res = dmtTest.getcipherDMTSignDM(cipherData, length);
                        Log.e("getcipherDMTSignDM", res + "");
                        if (res == 0x90) {
                            byte[] cipher = new byte[length[0]];
                            System.arraycopy(cipherData, 0, cipher, 0, cipher.length);
                            Bundle bundle = new Bundle();
                            bundle.putByteArray("data", cipher);
                            deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                        } else {
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.SIGNATURE_EN_FAIL);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_EN_FAIL));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                        }

                    } else {
                        Bundle bundle = new Bundle();
//                        bundle.putParcelableArrayList("NoPasswordTrack",(ArrayList)SignaturePad.mPoint);
                        bundle.putInt("code", ErrorDefine.SIGNATURE_INIT_FAIL);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_INIT_FAIL));
                        deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                    }
                } finally {
                    deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
                }
            }

        };

        DmtThreadPool.submit(runnable);


    }
    public static void setSignWorkKey(int index,int type,String workKey){
        if (type == 2){
            index += 20;
        }
        String workKeyPlain = SMUtil.SM4DecryptCBC(workKey,keyInfoUtil.getKey(keyInfoUtil.getMainKeyName(index)));
        keyInfoUtil.saveKey(keyInfoUtil.getWorkKeyName(4,index),workKeyPlain );
    }
    //加密轨迹数据
    public static String setSignEncryptTrack(String track,int type ,int index){
        if (type == 2){
            index += 20;
        }
        return SMUtil.SM4EncryptCBC(track,keyInfoUtil.getKey(keyInfoUtil.getWorkKeyName(4,index)));
    }
    /**
     * 签名设置主密钥
     * @param callback
     * @param mainKey
     * @param isOnMain
     */
    public static void setSignMainKey(DeviceCallback callback, String mainKey,int type,int index, boolean isOnMain) {
        if (type == 2){ //国密索引加10
            index += 20;
        }
        int finalIndex = index;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {

                try {
                    deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);

                    keyInfoUtil.saveKey(keyInfoUtil.getMainKeyName(finalIndex),mainKey);

                    Bundle bundle = new Bundle();
                    bundle.putString("data", SMUtil.SM4EncryptCBC("00000000000000000000000000000000",mainKey));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);


                } finally {
                    deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
                }
            }

        };

        DmtThreadPool.submit(runnable);


    }

    public static void setSM4PrimaryKey(DeviceCallback callback, byte[] sm4key, boolean isOnMain) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                try {
                    if (INIT_SIGN) {
                        byte[] verify = new byte[16];
                        int res = dmtTest.setSM4PrimaryKey(sm4key, verify);
                        Log.e("setSM4PrimaryKey", res + "==");
                        if (res == DmtProtocol.STATUS_OK) {
                            Log.e("verify", ByteTool.byte2hex(verify));
                            Bundle bundle = new Bundle();
                            bundle.putString("data", ByteTool.byte2hex(verify));
                            deliverResult(callback, Result.SUCCEED, bundle, isOnMain);

                        } else {

                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.SIGNATURE_SM4_FAIL);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_SM4_FAIL));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                        }

                    } else {

                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.SIGNATURE_INIT_FAIL);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_INIT_FAIL));
                        deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                    }
                } finally {
                    deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
                }
            }

        };

        DmtThreadPool.submit(runnable);


    }

    public static void transSM2PublicKey(DeviceCallback callback, boolean isOnMain) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                try {
                    if (INIT_SIGN) {

                        byte[] pubkey = new byte[64];
                        int res = dmtTest.transSM2Publickey(0, pubkey);
                        Log.e("transSM2Publickey", res + "===");
                        String pukStr = ByteTool.byte2hex(pubkey);
                        if (res == DmtProtocol.STATUS_OK) {

                            Log.e("pubkey", pukStr);
                            Bundle bundle = new Bundle();
                            bundle.putString("data", pukStr);
                            deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                        } else {

                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.SIGNATURE_SM2_FAIL);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_SM2_FAIL));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                        }
                    } else {

                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.SIGNATURE_INIT_FAIL);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SIGNATURE_INIT_FAIL));
                        deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                    }
                } finally {
                    deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
                }

            }

        };

        DmtThreadPool.submit(runnable);

    }
    @Deprecated
    public static void initSignPad() {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                int res = dmtTest.connectDMTSignDM();
                Log.e("initSignPad", "connectDMTSignDM--" + res);
                if (res != DmtProtocol.STATUS_OK) {
                    Log.e("connectDMTSignDM", "fail");
                    return;
                }
                StringBuffer DevVer = new StringBuffer();
                res = dmtTest.getversionDMTSignDM(DevVer);
                if (res == DmtProtocol.STATUS_OK) {

                    Log.e("getVer", "Ver:" + DevVer);
                    INIT_SIGN = true;

                } else {
                    INIT_SIGN = false;
                }
            }
        };

        DmtThreadPool.submit(runnable);

    }

    public static void setKeyValue(String key, String value) {
        Context ctx = MainActivity.context;
        SharedPreferences sp = ctx.getSharedPreferences(ConstDefine.SP_FILE_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        editor.commit();
    }

    public static String getValue(String key) {
        Context ctx = MainActivity.context;
        SharedPreferences sp = ctx.getSharedPreferences(ConstDefine.SP_FILE_NAME, MODE_PRIVATE);

        return sp.getString(key, "");
    }

    public static void setSerialCode(String code){
        code = code.trim();
        MainActivity.getmSys().DLL_SysWriteMtkSN((byte) code.length(),code.getBytes());
        LogUtil.e(TAG,"写入序列号是：" + code);
    }
    public static String getSerialCode(){
        byte[] b = new byte[64];
        int ret = MainActivity.getmSys().DLL_SysReadMtkSN(b);
        String codeStr = new String(b).trim();
        LogUtil.e(TAG,"ret =" + ret + "--读出的序列号是：" + codeStr);
        return codeStr;
    }

    //修改蓝牙名称
    public static void changeBlueName(String name){
        Context ctx = MainActivity.context;
        SharedPreferences sp = ctx.getSharedPreferences(ConstDefine.SP_FILE_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(ConstDefine.SP_KEY_BLUE_NAME, name);
        editor.commit();
    }





    /**********************************
     * soft sm2
     **************************************
     * @param deviceCallback*/
    public static SM2keyPair getSM2keypair(DeviceCallback deviceCallback) {
        SM2keyPair keypair = SMUtil.generatorSm2KeyPair();
        Bundle bundle = new Bundle();
        bundle.putString("data",keypair.pukX + keypair.pukY);
        deviceCallback.onSuccess(bundle);
        LogUtil.e(TAG,"private key =" + keypair.prvk + "\n X==" + keypair.pukX + "\n Y==" + keypair.pukY);
        return keypair;
    }

    public static byte[] SM2Decipher(String prvk, String content, int mode) {
        if (prvk.length() > 0) {
            byte[] buf = SMUtil.SM2PrvDecrypt(prvk, content, mode);
            return buf;
        }
        return null;

    }
    /*************************************************************************/
    /**
     * 获取唯一标识
     *
     * @param
     * @return
     */
    public static String getDeviceId() {

//        String btAddress = BlueServer.getBTAddress();
        String btAddress = getValue(ConstDefine.SP_KEY_BLUE_Device_ID);
//        String mac = MacUtils.getMac();
//        return getMacFromDevice();
        btAddress = "ZG" + btAddress.replace(":","");
        return btAddress;
    }
    public static String getDeviceSerial(){
        return Build.SERIAL;
    }
    /**
     * 获取版本号
     *
     * @return 当前应用的版本号
     */
    public static String getVersion() {
        try {
            PackageManager manager = MainActivity.context.getPackageManager();
            PackageInfo info = manager.getPackageInfo(MainActivity.context.getPackageName(), 0);
            String version = info.versionName;
            return version;
        } catch (Exception e) {
            e.printStackTrace();
            return "无法获取到版本号";
        }
    }
    public static String getDeviceVersion(){
        PackageManager manager = MainActivity.context.getPackageManager();
        String name = null;
//        Build.DISPLAY
//        try {
//            PackageInfo info = manager.getPackageInfo(MainActivity.context.getPackageName(), 0);
            name = Build.DISPLAY;
//            Log.e(TAG,"\nBuild.BOARD："+Build.BOARD+"\nBuild.BRAND："+Build.BRAND+"\nBuild.DEVICE："+Build.DEVICE+"\nBuild.DISPLAY："+Build.DISPLAY
//            +"\nBuild.FINGERPRINT："+Build.FINGERPRINT+"\nBuild.SERIAL："+Build.SERIAL+"\nBuild.MANUFACTURER："+Build.MANUFACTURER+"\nBuild.MODEL："+Build.MODEL
//            +"\nBuild.HARDWARE："+Build.HARDWARE+"\nBuild.PRODUCT："+Build.PRODUCT+"\nBuild.VERSION.INCREMENTAL："+Build.VERSION.INCREMENTAL
//            +"\nBuild.VERSION.RELEASE："+Build.VERSION.RELEASE+"\nBuild.VERSION.SDK_INT："+Build.VERSION.SDK_INT+"\nBuild.USER："+Build.USER);

//        } catch (PackageManager.NameNotFoundException e) {
//            e.printStackTrace();
//        }

        return name;
    }


    /**********************************
     * 指纹模块
     ***************************************/


    private static FingerDevice mFingerDevice = null;
    private static zzFingerAlg mZzFingerAlg = null;

    private static Future<?> getFingerFeatureTask;


    public static void getFingerFeature(final DeviceCallback callback, int timeOutMs, final boolean isOnMain) {
        getFingerFeatureTask = fingerThreadPool.submit(new Runnable() {
            @Override
            public void run() {
                mFingerDevice = new FingerDevice();
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)1);
                byte[] ver = new byte[30];
                byte[] errMsg = new byte[200];
                int ret = -1;
                try {
                    InitFinger();
                    if (!BuildConfig.FLAVOR.equals(ConstDefine.FLAVOR_GZNX)){ //中性版本才去兼容中正的指纹模块 提高读取速度
                        for (int i = 0; i < 1; i++) {

                            ret = mFingerDevice.GetDevVersion(mPortPath,115200,ver.length,ver,errMsg);

                            LogUtil.e(TAG,"ret == " + ret + "----ver == " + new String(ver).trim() + "----" + new String(errMsg).trim());
                            if (ret == 0) break;
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

                if(ret == 0){ //中正模块
                    int nResult = 0;
                    byte[] m_B64_bFeature = new byte[344];
                    try {
                        nResult = mFingerDevice.GetFeature(mPortPath, 115200, timeOutMs, m_B64_bFeature, errMsg);
                        LogUtil.e(TAG, " nResult == " + nResult);
                        if (nResult != 0) { //读取错误

                            Bundle bundle = new Bundle();
                            bundle.putInt("code", nResult);
                            bundle.putString("message", new String(errMsg, "GBK").trim());
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                        } else {
                            String feat_b64 = new String(m_B64_bFeature).trim();
                            Bundle bundle = new Bundle();
                            JSONObject jb = new JSONObject();
                            try {
                                jb.put("feature",feat_b64);
                                jb.put("factory",new String(ver).trim());
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            bundle.putString("data", jb.toString());
                            deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                        }
                        MainActivity.getmSys().DLL_SysLedControl((byte) 1, (byte) 0);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }


                }else {

                    // TODO 添加维尔指纹支持
                    WellFingerprintModule wellFinger = WellFingerprintModule.getInstance();
                    wellFinger.init();
                    String version = wellFinger.getVersion();
                    if (!TextUtils.isEmpty(version)) {
                        try {

                            byte[] temp = new byte[384];
                            int[] len = new int[1];
                            ret = wellFinger.startFeatureTask(timeOutMs, temp, len);

                            if (ret != 0) {
                                Bundle bundle = new Bundle();
                                bundle.putInt("code", ret);
                                bundle.putString("message", ErrorDefine.getErrorDescribe(ret));
                                deliverResult(callback, Result.ERROR, bundle, isOnMain);
                                return;
                            }
                            byte[] feature = new byte[len[0]];
                            System.arraycopy(temp, 0, feature, 0, len[0]);
                            byte[] bytes = WellFingerprintModule.splitData(feature);
                            String feaStr = ByteTool.byte2hex(bytes);
                            LogUtil.i(TAG,"收到指纹特征码：" + feaStr);


                            Bundle bundle = new Bundle();
                            bundle.putString("feature", feaStr);

                            bundle.putInt("fingerType", 2);
                            JSONObject jb = new JSONObject();
                            try {
                                jb.put("feature",feaStr);
                                jb.put("factory",version);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            bundle.putString("data",jb.toString());
                            deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                            return;
                        } finally {
                            MainActivity.getmSys().DLL_SysLedControl((byte) 1, (byte) 0);
                            wellFinger.recycle();
                        }
                    }

                    //天诚指纹
//            InitFinger();
                    mTcFingerClientApi = new TcFingerClientApi(MainActivity.context);
                    mTcFingerClientApi.DLL_OpenDevice(mPortPath, mBaudrate);
                    mTcFingerClientApi.clear();
//            FingerResult result = mTcFingerClientApi.DLL_tcGetDevSn();
//            String devSN = result.getResult();
//            LogUtil.e(TAG,"DLL_tcGetDevSn == " + devSN);
                    mTcFingerClientApi.DLL_tcGetFeature(timeOutMs, new com.eyecool.fp.client.Callback() {

                        @Override
                        public void onSuccess(com.eyecool.fp.entity.FingerResult result) {
                            byte[] template = result.getTemplate();

//				byte[] gbBytes = FpImage.tcFeaToGB(template);
//				byte[] feaBytes = FpImage.gbToTcFea(gbBytes);

                            mTemplate = template;
//                    String feaStr = Base64.encodeToString(template, Base64.NO_WRAP);
                            String feaStr = new String(template);
                            Bundle bundle = new Bundle();
                            JSONObject jb = new JSONObject();
                            try {
                                jb.put("feature",feaStr);
                                jb.put("factory","tc");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            bundle.putString("data", jb.toString());
                            deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                            MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);
                            mTcFingerClientApi.clear();
                            mTcFingerClientApi.DLL_FingerRelease();
                        }

                        @Override
                        public void onError(int errorCode) {
                            // 超时是 -13   取消是 -9
                            LogUtil.e(TAG,"DLL_tcGetFeature errorCode == " + errorCode);
                            if (errorCode == -13){
                                errorCode = ErrorDefine.FINGERPRINT_TIMEOUT;
                            }else{  // -9
                                errorCode = ErrorDefine.FINGERPRINT_CANCEL;
                            }
                            mTcFingerClientApi.clear();
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", errorCode);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(errorCode));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                            MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);
                        }
                    });
                }
            }
        });




    }

    public static void registFinger(final DeviceCallback callback, int timeOutMs, final boolean isOnMain){
        getFingerFeatureTask = fingerThreadPool.submit(new Runnable() {
            @Override
            public void run() {
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)1);
                Bundle bundle = new Bundle();
                mTcFingerClientApi.DLL_tcRegistFinger(timeOutMs, new com.eyecool.fp.client.Callback() {
                    @Override
                    public void onSuccess(com.eyecool.fp.entity.FingerResult fingerResult) {
                        LogUtil.e(TAG,"fingerResult === " + fingerResult.getResult());
                        bundle.putString("data",fingerResult.getResult());
                        deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                    }

                    @Override
                    public void onError(int i) {
                        LogUtil.e(TAG,"fingerResult error === " +i);
                        bundle.putInt("code",i);
                        bundle.putString("message","regist failed");
                        deliverResult(callback, Result.ERROR, bundle, isOnMain);
                    }
                });
            }
        });
    }

    public static void fingerCancel(){
        mTcFingerClientApi.DLL_tcCancel();
        mTcFingerClientApi.DLL_FingerRelease();
        MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);
        if (getFingerFeatureTask != null)
            getFingerFeatureTask.cancel(true);
        if (fingerPrintRunnable != null)
            fingerPrintRunnable.stopRun();
        WellFingerprintModule.getInstance().recycle();
    }

    public static String getFingerVersion(DeviceCallback callback,boolean isOnMain){

        fingerThreadPool.submit(new Runnable() {
            @Override
            public void run() {

                Bundle bundle = new Bundle();
                WellFingerprintModule module = WellFingerprintModule.getInstance();
                module.init();
                String version = module.getVersion();
                if (null == version){
                    InitFinger();
                    mFingerDevice = new FingerDevice();
                    deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                    MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)1);
                    byte[] ver = new byte[30];
                    byte[] errMsg = new byte[200];
                    int ret = -1;
                    try {

                        if (!BuildConfig.FLAVOR.equals(ConstDefine.FLAVOR_GZNX)){ //中性版本才去兼容中正的指纹模块 提高读取速度
                            for (int i = 0; i < 1; i++) {

                                ret = mFingerDevice.GetDevVersion(mPortPath,115200,ver.length,ver,errMsg);
                                 if (ret == 0) {
                                    version = new String(ver).trim();
                                    LogUtil.e(TAG,"ret == " + ret + "----ver == " + new String(ver).trim() + "----" + new String(errMsg).trim());

                                    break;
                                }
                            }
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }


                    if (ret != 0){
                        com.eyecool.fp.entity.FingerResult fingerResult = mTcFingerClientApi.DLL_tcGetDevSn();
                        version = fingerResult.getResult();
                    }


                }
                bundle.putString("data", version);
                deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);

            }
        });


        return "";
    }


    public static int getFingerPic(final DeviceCallback callback, int timeOutMs, final boolean isOnMain) {
        MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)1);
        InitFinger();
        deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
        mTcFingerClientApi.DLL_tcSetBaudRate(7);
        mBaudrate = 115200;
        mTcFingerClientApi.DLL_OpenDevice(mPortPath, mBaudrate);

        mTcFingerClientApi.DLL_tcGetImage(timeOutMs, new com.eyecool.fp.client.Callback() {
            @Override
            public void onSuccess(com.eyecool.fp.entity.FingerResult result) {

                Bitmap bitmap = BitmapFactory.decodeByteArray(
                        result.getImgBytes(), 0, result.getImgBytes().length);
//                Bitmap bitmap2 = FpCoder.getRedTransparentBitmap(bitmap);
                Bitmap bitmap2 = FpCoder.getTransparentBitmap(bitmap, Color.RED);
//                mImageView.setImageBitmap(bitmap2);
//                fingerImage = bitmap;
                LogUtil.e(TAG,"获取的指纹图片大小getByteCount：" + bitmap2.getByteCount());
                Bundle bundle = new Bundle();
//                System.arraycopy(data,28,buff,0,len[0]-28);
                bundle.putString("data", "");
                bundle.putInt("zip",1);
                byte[] bytes = Bitmap2Bytes(bitmap2);
                bundle.putByteArray("imgBuff",bytes);
                LogUtil.e(TAG,"获取的指纹图片字节数：" + bytes.length);
                deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
//                tesoFingerPrintModule.lightOff();
                mTcFingerClientApi.DLL_FingerRelease(); //关闭指纹
                MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);
                reConnect(9600);
            }
            @Override
            public void onError(int errorCode) {
                Bundle bundle = new Bundle();
                bundle.putInt("code", ErrorDefine.FINGERPRINT_FREATURE_TIMEOUT);
                bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.FINGERPRINT_FREATURE_TIMEOUT));
                deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                MainActivity.getmSys().DLL_SysLedControl((byte) 1,(byte)0);
                reConnect(9600);
            }
        });
            return 0;
    }
    public static byte[] Bitmap2Bytes(Bitmap bm) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }
    private static void reConnect(int baudRate) {
        mTcFingerClientApi.DLL_tcSetBaudRate(3);
        mBaudrate = baudRate;
        mTcFingerClientApi.DLL_OpenDevice(mPortPath, mBaudrate);
    }

    public static int Encode0x30(byte[] chDst, byte[] pSrc, int nLen) {
//        byte[] chDst = pDst;
        byte[] bySrc = pSrc;

        /* 若返回指针为NULL，则为求取存储所需的字节长度(含'\0') */
        if (nLen < 0)
            return (-3);
        if (chDst == null) {
            return -(2 * nLen + 1);
        }
        if (pSrc == null) {
            return (-3);
        }

        /* 一个字节折成两个低4位或上0x30的可见字符(高在前) */
        for (int i = 0; i < nLen; i++) {
            chDst[i * 2] = (byte) (0x30 | (((bySrc[i]) >> 4) & 0x0F));
            chDst[i * 2 + 1] = (byte) (0x30 | ((bySrc[i]) & 0x0F));
        }

        chDst[nLen * 2] = '\0';
        return 0;
    }

    public static int fingerMatch(byte[] feature,byte[] templet,final DeviceCallback callback, int timeOutMs, final boolean isOnMain){
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (ConstDefine.getFingerprintPort() == null) {
            tesoFingerPrintModule.PowerOn();

            mUsbUtil = USBComm.getInstance(MainActivity.context);

            mUsbUtil.setConnectListener(new OnConnectListener() {

                @Override
                public void onConnected(int type, TcFingerClient client, USBComm usbComm) {

                    if (type == 1) {
                        mClient = client;
                        if (mClient == null) {
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.FINGERPRINT_FREATURE_ERR);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.FINGERPRINT_FREATURE_ERR));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                            return;
                        }
                        FingerResult result =  mClient.tcMatch(feature,templet);

                        Log.e("result",result.getStatus()+"==");

                       if(result.getStatus()>=0){

                           Bundle bundle = new Bundle();
                           bundle.putInt("type", 1);
                           deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                           tesoFingerPrintModule.lightOff();

                           deliverResult(callback, DeviceInterface.Result.COMPLETED, new Bundle(), isOnMain);
                           tesoFingerPrintModule.PowerOff();
                           mUsbUtil.disconnectDevice();
                       }else{

                           Bundle bundle = new Bundle();
                           bundle.putInt("code", ErrorDefine.FINGERPRINT_MATCH_ERR);
                           bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.FINGERPRINT_MATCH_ERR));
                           deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                           tesoFingerPrintModule.lightOff();
                           tesoFingerPrintModule.PowerOff();
                           mUsbUtil.disconnectDevice();
                           deliverResult(callback, DeviceInterface.Result.COMPLETED, new Bundle(), isOnMain);
                       }


                    }else{

                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.FINGERPRINT_NO_HAVE);
                        bundle.putString("message", "Finger Unsupported");
                        deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);

                    }



                }

                @Override
                public void onConnectFailed(int code, String msg) {

                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.FINGERPRINT_RESPOND_ERR);
                    bundle.putString("message", "Finger error");
                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);


                }
            });
            deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
            SystemClock.sleep(500);
            mUsbUtil.connectDevice();
            tesoFingerPrintModule.lightOn();


            return 0;
        } else {

            if (callback == null) {

                return ErrorDefine.NO_CALLBACK;
            }
            if (fingerPrintRunnable != null) {
                fingerPrintRunnable.stopRun();
                fingerPrintRunnable = null;
            }
            fingerPrintRunnable = new FingerPrintRunnable(FingerPrintRunnable.Action.GET_PIC, callback, timeOutMs, isOnMain);
            fingerThreadPool.execute(fingerPrintRunnable);
            return 0;
        }

    }


    public static int getTemplet(final DeviceCallback callback, int timeOutMs, final boolean isOnMain){
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (ConstDefine.getFingerprintPort() == null) {
            tesoFingerPrintModule.PowerOn();

            mUsbUtil = USBComm.getInstance(MainActivity.context);

            mUsbUtil.setConnectListener(new OnConnectListener() {

                @Override
                public void onConnected(int type, TcFingerClient client, USBComm usbComm) {

                    if (type == 1) {
                        mClient = client;
                        if (mClient == null) {
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.FINGERPRINT_FREATURE_ERR);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.FINGERPRINT_FREATURE_ERR));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                            return;
                        }
                        mClient.tcEnroll(new Callback() {
                            @Override
                            public void onSuccess(FingerResult result) {


                                byte[] feature = result.getTemplate();
                                Log.e("feature",new String(feature)+"!!!");
                                Bundle bundle = new Bundle();
                                bundle.putInt("type", 1);
                                bundle.putString("data", new String(feature).trim());
                                deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                                tesoFingerPrintModule.lightOff();
                                deliverResult(callback, DeviceInterface.Result.COMPLETED, new Bundle(), isOnMain);
                                tesoFingerPrintModule.PowerOff();
                                mUsbUtil.disconnectDevice();

                            }
                            @Override
                            public void onProcess(int code, byte[] img) {
                                Log.e("onProcess",code+"---");
                                super.onProcess(code, img);
                                switch (code) {
                                    case FpConst.TCY_CAPTUREIMAGE:
                                        MainActivity.startFingerPrint(timeOutMs);
                                        break;
                                    case FpConst.TCY_GETIMAGE:
                                        MainActivity.stopFingerPrint();
                                        break;
                                    case FpConst.TCY_TOLV:
//
                                        break;
                                    default:
                                        break;
                                }
                            }
                            @Override
                            public void onError(int errorCode) {
                                Log.e("onError",errorCode+"!!!");
                                Bundle bundle = new Bundle();
                                bundle.putInt("code", ErrorDefine.FINGERPRINT_ENROLL);
                                bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.FINGERPRINT_ENROLL));
                                deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                                return;


                            }
                        },timeOutMs);




                    }else{

                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.FINGERPRINT_NO_HAVE);
                        bundle.putString("message", "Finger Unsupported");
                        deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);

                    }



                }

                @Override
                public void onConnectFailed(int code, String msg) {

                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.FINGERPRINT_RESPOND_ERR);
                    bundle.putString("message", "Finger error");
                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);


                }
            });
            deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
            SystemClock.sleep(500);
            mUsbUtil.connectDevice();
            tesoFingerPrintModule.lightOn();


            return 0;
        } else {

            if (callback == null) {

                return ErrorDefine.NO_CALLBACK;
            }
            if (fingerPrintRunnable != null) {
                fingerPrintRunnable.stopRun();
                fingerPrintRunnable = null;
            }
            fingerPrintRunnable = new FingerPrintRunnable(FingerPrintRunnable.Action.GET_PIC, callback, timeOutMs, isOnMain);
            fingerThreadPool.execute(fingerPrintRunnable);
            return 0;
        }

    }


    public static int getFingerVer(final DeviceCallback callback, int timeOutMs, final boolean isOnMain) {

        String version = getFingerVersion(callback,isOnMain);
//        Bundle bundle = new Bundle();
//        if(TextUtils.isEmpty(version)){
//            bundle.putInt("code", ErrorDefine.FINGERPRINT_RESPOND_ERR);
//            bundle.putString("message", "Finger error");
//            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
//        }else {
//            bundle.putString("data", version);
//            deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
//        }


//        if (callback == null)
//            return ErrorDefine.NO_CALLBACK;
//
//        /**
//         *
//         * usb 指纹模块
//         */
//        if (ConstDefine.getFingerprintPort() == null) {
//
//
//            tesoFingerPrintModule.PowerOn();
//
//            mUsbUtil = USBComm.getInstance(MainActivity.context);
//            mUsbUtil.setConnectListener(new OnConnectListener() {
//
//                @Override
//                public void onConnected(int type, TcFingerClient client, USBComm usbComm) {
//                    Log.e("fingerType", type + "!!!");
//                    if (type == 1) {
//                        mClient = client;
//
//                        Bundle bundle = new Bundle();
//                        bundle.putString("data", "TC");
//
//                        deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
//                        tesoFingerPrintModule.lightOff();
//                        tesoFingerPrintModule.PowerOff();
//                    } else if (type == 2) {
//
//                        Bundle bundle = new Bundle();
//                        bundle.putString("data", MXVersion.strVersion);
//                        Log.e("2ver:", MXVersion.strVersion);
//                        deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
//                        mUsbUtil.disconnectDevice();
//                        mUsbUtil.closeDev();
//                    } else if (type == 3) {
//                        String[] version = usbComm.getFpVersion();
//
//                        if (version[0].equals("0")) {
//
//                            Log.e("3ver", version[1]);
//                            Bundle bundle = new Bundle();
//                            bundle.putString("data", "well");
//                            deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
//                            mUsbUtil.disconnectDevice();
//                            mUsbUtil.closeDev();
//                        }
//
//
//                    }
//                    tesoFingerPrintModule.lightOff();
//                    tesoFingerPrintModule.PowerOff();
//
//                }
//
//                @Override
//                public void onConnectFailed(int code, String msg) {
//
//                    Bundle bundle = new Bundle();
//                    bundle.putInt("code", ErrorDefine.FINGERPRINT_RESPOND_ERR);
//                    bundle.putString("message", "Finger error");
//                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
//
//
//                }
//            });
//            deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
//            SystemClock.sleep(500);
//            mUsbUtil.connectDevice();
//
//            return 0;
//
//
//        } else {
//            if (fingerPrintRunnable != null) {
//                fingerPrintRunnable.stopRun();
//                fingerPrintRunnable = null;
//            }
//            fingerPrintRunnable = new FingerPrintRunnable(FingerPrintRunnable.Action.READ_VER, callback, timeOutMs, isOnMain);
//            fingerThreadPool.execute(fingerPrintRunnable);
            return 0;
//        }

    }

    public static void cancelFingerPrint() {

        SystemClock.sleep(1500);
        if (USBComm.TYPE == 3) {
            Log.e("well", "cancelFingerPrint");
            try {
                FpDriverV22.FPICancel();
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
        }

        if (mClient != null) {

            mClient.tcCancel();
            return;
        }
        if (fingerPrintRunnable != null) {
            fingerPrintRunnable.stopRun();
            fingerPrintRunnable = null;
        }
    }


    /*******************************密码键盘******************************************/


    public static void inputTMKOnBoard(DeviceCallback callback, boolean isOnMain, int timeOut) {

        if (keyInputRunnable != null) {
            keyInputRunnable.stopRun();
            keyInputRunnable = null;
        }
        keyInputRunnable = new KeyInputRunnable(callback, isOnMain, timeOut);
        keyThreadPool.submit(keyInputRunnable);

    }


    public static int decryptByKeyBoard(String keyindex, String in, byte[] out, int[] len) {
        Log.e("decryptByKeyBoard", "---");
        int ret = keyBoardModule.setEncryptMode(CipherKeyBoardModule.WORK_KEY_P, SM4_MODE_MAIN);// 国密更新密钥
//        int ret  = keyBoardModule.setEncryptMode(CipherKeyBoardModule.WORK_KEY_P, DES_MODE_MAIN);// 3DES更新密钥
        keyBoardModule.setEncryptKey(keyindex, "00");        //国密更新密钥
        ret = keyBoardModule.decrypt(in, out, len);

        return ret;

    }
    @Deprecated
    public static int updateMainKeyByOld(final String keyIndex, final String keyData, final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                byte[] realKeyData = new byte[32];
                int[] length = new int[1];
                decryptByKeyBoard(keyIndex, keyData, realKeyData, length);
                Log.e("buff", ByteTool.byte2hex(realKeyData, 0, length[0], true));
                deliverResult(callback, Result.START, null, isOnMain);

                byte[] check = new byte[4];
                int res = keyBoardModule.injectionMainKey(keyIndex, ByteTool.byte2hex(realKeyData, 0, length[0], false).trim(), check);

                if (res == 0) {
                    Bundle bundle = new Bundle();
                    bundle.putString("data", ByteTool.byte2hex(check));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.INPUT_MAINKEY_ERR);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.INPUT_MAINKEY_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                }
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);

            }
        };
        keyThreadPool.execute(r);
        return 0;
    }

    @Deprecated
    public static int inputMainKeyByOld(final String keyIndex, final String keyData, final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                byte[] realKeyData = new byte[32];
                int[] length = new int[1];
                decryptByKeyBoard("00", keyData, realKeyData, length);
                Log.e("buff", ByteTool.byte2hex(realKeyData, 0, length[0], true));
                deliverResult(callback, Result.START, null, isOnMain);

                byte[] check = new byte[4];
                int res = keyBoardModule.injectionMainKey(keyIndex, ByteTool.byte2hex(realKeyData, 0, length[0], false).trim(), check);

                if (res == 0) {
                    Bundle bundle = new Bundle();
                    bundle.putString("data", ByteTool.byte2hex(check));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.INPUT_MAINKEY_ERR);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.INPUT_MAINKEY_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                }
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);

            }
        };
        keyThreadPool.execute(r);
        return 0;
    }

    @Deprecated
    public static int calcMAC(int macMode, int mainKey, int workIndex, byte[] data, final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Log.e("calcMAC", "calcMAC");
        Runnable r = new Runnable() {
            @Override
            public void run() {
                if (macMode == 0x01) {
                    //x99
                    keyBoardModule.setEncryptMode("06", "03");
                }
                if (macMode == 0x02) {
                    //x9.19
                    keyBoardModule.setEncryptMode("06", "01");
                }
                deliverResult(callback, Result.START, null, isOnMain);

                String index = String.format("%02d", Integer.valueOf(mainKey));
                String windex = String.format("%02d", Integer.valueOf(workIndex));
                keyBoardModule.setEncryptKey(index, windex);//mac密钥用的0x03的工作密钥
                byte[] buff = new byte[2048];
                int[] len = new int[1];
                byte[] rebuff;
                if (data.length <= 256) {
                    int res = keyBoardModule.getMac(ByteTool.byte2hex(data), buff, len);
                    if(res!=0){
                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.CALC_MAC_ERROR);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.CALC_MAC_ERROR));
                        deliverResult(callback, Result.ERROR, bundle, isOnMain);

                    }else {
                        Log.e("buff", ByteTool.byte2hex(buff, 0, len[0], false));
                        rebuff = new byte[len[0]];
                        System.arraycopy(buff, 0, rebuff, 0, rebuff.length);
                        Bundle bundle = new Bundle();
                        bundle.putByteArray("data",rebuff);
                        deliverResult(callback, Result.SUCCEED, bundle, isOnMain);

                    }
                } else {
                    int res = keyBoardModule.getMacBD(data, buff, len);
                    Log.e("BDbuff", ByteTool.byte2hex(buff, 0, len[0], false));
                    if(res!=0){
                        Bundle bundle = new Bundle();
                        bundle.putInt("code", ErrorDefine.CALC_MAC_ERROR);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.CALC_MAC_ERROR));
                        deliverResult(callback, Result.ERROR, bundle, isOnMain);

                    }else {
                        Log.e("buff", ByteTool.byte2hex(buff, 0, len[0], false));
                        rebuff = new byte[len[0]];
                        System.arraycopy(buff, 0, rebuff, 0, rebuff.length);
                        Bundle bundle = new Bundle();
                        bundle.putByteArray("data",rebuff);
                        deliverResult(callback, Result.SUCCEED, bundle, isOnMain);

                    }

                }

                Log.e("calcMAC", "mac校验");


                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
            }
        };
        keyThreadPool.execute(r);
        return 0;
    }
    public static int resetKeyBoardClear(final DeviceCallback callback,final String resetkeyData ,final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int ret = MainActivity.getmMainPci().DLL_PciClearAllAppKeys();
                LogUtil.e(TAG,"ret == " + ret);
                deliverResult(callback, Result.SUCCEED, new Bundle(), isOnMain);
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);

            }
        };
        keyThreadPool.execute(r);
        return 0;
    }
    @Deprecated
    public static int resetKeyBoard(final DeviceCallback callback,final String resetkeyData ,final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Runnable r = new Runnable() {
            @Override
            public void run() {


                keyBoardModule.reset(true);
                byte[] check = new byte[4];
                byte[] keyData = new byte[16];

                for (int i = 0; i < 16; i++) {
                    String keyIndex = String.format("%02d", i);
                    Arrays.fill(keyData, (byte) 0x38);
                    int res;
                    if(resetkeyData != null && !resetkeyData.equals("")){
                        res = keyBoardModule.injectionMainKey(keyIndex, resetkeyData, check);
                    }else{
                        res = keyBoardModule.injectionMainKey(keyIndex, ByteTool.byte2hex(keyData), check);
                    }
                    Arrays.fill(keyData, (byte) 0x30);
                    res = keyBoardModule.injectionWorkKey(keyIndex, keyIndex, ByteTool.byte2hex(keyData), check);

                }
//                keyBoardModule.reset(false);
                deliverResult(callback, Result.SUCCEED, new Bundle(), isOnMain);
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
            }
        };
        keyThreadPool.execute(r);
        return 0;
    }


    /**
     * 取消输入
     */
    public static void cancelKeyBoardInput() {


        if (keyBoardRunnable != null && keyBoardRunnable.isInputting()) {
            keyBoardRunnable.stopRun();
            keyBoardRunnable = null;
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    LogUtil.e(TAG,"关闭了密码键盘------------");
                    MainActivity.getmMainPci().DLL_PciKbClose(); //关闭键盘
//                    keyBoardModule.cancelInput();
//                    keyBoardModule.flush();
                }
            };
            keyThreadPool.submit(r);
        } else if (keyBoardRunnable != null) {
            keyBoardRunnable.stopRun();
//            keyBoardModule.flush();
            keyBoardRunnable = null;

        }
    }

    /**
     * 设置密码键盘加密模式
     *
     * @return
     */
    @Deprecated
    public static int setKeyEncryptMode(String mode) {

        int res;
        //SM4加密
        if (mode == DeviceInterface.SM4_MODE) {
            Log.e("setKeyEncryptMode", "SM4");
            res = keyBoardModule.setEncryptMode(CipherKeyBoardModule.WORK_KEY_P, mode);
            res = keyBoardModule.setEncryptMode("05", "05");
//            res = keyBoardModule.setEncryptMode("05", "00");
            return res;
        }

        //3DES加密
        if (mode == DeviceInterface.THREE_DES_MODE) {
            res = keyBoardModule.setEncryptMode(CipherKeyBoardModule.MASTER_KEY_P, mode);
            if (res != 0) {
                return res;
            }
            res = keyBoardModule.setEncryptMode(CipherKeyBoardModule.WORK_KEY_P, mode);
            res = keyBoardModule.setEncryptMode("05", "05");
//        res = keyBoardModule.setEncryptMode("05", "00");
            return res;
        }

        //不加密

//            res = keyBoardModule.setEncryptMode(CipherKeyBoardModule.MASTER_KEY_P, mode);
//            if (res != 0) {
//                return res;
//            }
//            res = keyBoardModule.setEncryptMode(CipherKeyBoardModule.WORK_KEY_P, mode);
//            res = keyBoardModule.setEncryptMode("01", "10");
//        res = keyBoardModule.setEncryptMode("05", "00");
        return 0;

    }

    @Deprecated
    public static void keySetEncryptMode(int encrypt, String endType, String activeMkey, String activeWkey, final DeviceCallback callback, final boolean isOnMain) {
        if (keyBoardRunnable != null) {
            keyBoardRunnable.stopRun();
        }
        Log.e("encrypt:", "==" + encrypt);
        Runnable r = new Runnable() {
            @Override
            public void run() {

//                if (keyBoardRunnable != null && keyBoardRunnable.getAlreadyInputlength() > 0) {
//
//                    keyBoardModule.cancelInput();
//                    keyBoardModule.flush();
//                }
                int res = 0;
                if (encrypt == KEY_SM) {
//                    res = setKeyEncryptMode(SM4_MODE);
                    isEncrypted = KEY_SM;
                    Log.e("sm4res:", res + "---");
                } else if (encrypt == KEY_3DES) {
//                    res = setKeyEncryptMode(THREE_DES_MODE);
                    isEncrypted = KEY_3DES;
                    Log.e("3desres:", res + "---");
                } else if (encrypt == KEY_NOENCRYPTION) {
//                    res = setKeyEncryptMode(NO_ENCRYPTION);
                    isEncrypted = KEY_NOENCRYPTION;
                    Log.e("noencry:", res + "---");
                }
                if (endType != null) {
//                    res = keyBoardModule.setEncryptMode("05", endType);

                    Log.e("setEncryptMode", res + "---" + endType);
                }

                if (activeMkey != null && activeWkey != null) {
//                    res = keyBoardModule.setEncryptKey(activeMkey, activeWkey);

                    Log.e("setEncryptKey", res + "---");
                }


                if (res == 0) {
                    Bundle bundle = new Bundle();
                    bundle.putString("data", res + "");
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.INPUT_MAINKEY_ERR);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.INPUT_MAINKEY_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);

                }
            }
        };
        keyThreadPool.submit(r);

    }

    /**
     * 启动密码键盘输入
     *
     * @param cardNo
     * @param masterKeyIndex
     * @param workKeyIndex
     * @param pwdLen
     * @param timeOutSec
     * @param encryptMode
     * @param callback
     * @param isOnMain
     * @return
     */
    public static int startInputPwd(final String cardNo, final String masterKeyIndex, final String workKeyIndex, final String pwdLen, final String timeOutSec, final int encryptMode,final int inputTimes, final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;

        if (keyBoardRunnable != null) {
            keyBoardRunnable.stopRun();
        }

        try {
            if (isEncrypted == KEY_NOENCRYPTION) {
                keyBoardRunnable = new KeyBoardRunnable(cardNo, masterKeyIndex, workKeyIndex, pwdLen, timeOutSec, encryptMode,inputTimes, callback, isOnMain, false);
            } else {
                keyBoardRunnable = new KeyBoardRunnable(cardNo, masterKeyIndex, workKeyIndex, pwdLen, timeOutSec, encryptMode,inputTimes, callback, isOnMain, true);
            }
            keyThreadPool.submit(keyBoardRunnable);
        } catch (NumberFormatException e) {
//            keyBoardModule.flush();
            Bundle bundle = new Bundle();
            bundle.putInt("code", ErrorDefine.KEY_NUMFORMAT_ERR);
            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.KEY_NUMFORMAT_ERR));
            deliverResult(callback, Result.ERROR, bundle, isOnMain);
        }


        return 0;
    }

    /**
     * 注入主密钥
     *
     * @param keyIndex
     * @param keyData
     * @mode 写入模式 0x00明文写入  0x81 解密写入  0x01加密写入
     * @return
     */
    public static int inputCipherMainKey(final String keyIndex, final String keyData,final int encryptType,final int mode,
                                         final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        byte type ;  // 0 --国际 TMK     3--国密SM4
        if(encryptType == 1){ //国际3DES
            type = 0;
        }else { //国密 SM4
            type = 3;
        }
        byte i = (byte) Integer.parseInt(keyIndex); //秘钥索引值为 0-5
        if(i < 0 || i >5){
            i = 0;
        }
        final byte index = i;

        Runnable r = new Runnable() {
            @Override
            public void run() {

                deliverResult(callback, Result.START, null, isOnMain);
                byte[] check = new byte[16];
                if(encryptType == 1)
                    check = new byte[8];
                int res = -1;
//                byte mode = 0;  // 0x00明文写入  0x81 解密写入  0x01加密写入
                byte[] keyDataByte = ByteTool.hexStr2Bytes(keyData);
                String mainKeyName;
                if (encryptType == 1)  //3DES  密钥索引 + 10
                    mainKeyName = keyInfoUtil.getMainKeyName(index + 10);
                else //国密 SM4
                    mainKeyName = keyInfoUtil.getMainKeyName(index);

                keyInfoUtil.saveKey(mainKeyName,keyData);
                if (MainActivity.isWakeUp){
                    try {
                        Thread.sleep(2500);
                        LogUtil.e(TAG,"--sleep 2500");
                        MainActivity.isWakeUp = false;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                res = MainActivity.getmMainPci().DLL_PciWriteMKey(type, index, (byte)16, keyDataByte, (byte) mode,check);
                LogUtil.e(TAG,"--DLL_PciWriteMKey res == " + res);

                Bundle bundle = new Bundle();
                if (res == 0) {
                    bundle.putString("data", ByteTool.byte2hex(check));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    bundle.putInt("code", res);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.INPUT_MAINKEY_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                }
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);


            }
        };
        keyThreadPool.execute(r);
        return 0;
    }


    /**
     * 注入工作密钥
     *
     * @param MainKeyIndex
     * @param workKeyIndex
     * @param workKey
     * @param encryptType 1 des 2 sm4
     * @param mode //0x00明文写入  0x81 解密写入  0x01加密写入
     * @param keyType 1 pin  2 mac 3 calculate
     * @return
     */
    public static int inputCipherWorkKey(final String MainKeyIndex, final String workKeyIndex,
                                         final String workKey,final int encryptType,final int mode,final int keyType,
                                         final DeviceCallback callback, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
//        int type = 8;  // 5 PINK   6 MACK  7 DESK
                        //8 SM4_PINK   9  SM4_MACK   10 SM4_DESK

        byte type = 8 ;
        if(encryptType == 1){ //国际3DES

            switch (keyType){
                case 1:
                    type = 5;
                    break;
                case 2:
                    type = 6;
                    break;
                case 3:
                    type = 7;
                    break;
            }

        }else { //国密 SM4

            switch (keyType){
                case 1:
                    type = 0x08;
                    break;
                case 2:
                    type = 0x09;
                    break;
                case 3:
                    type = 0x0A;
                    break;
            }
        }
        byte i = (byte) Integer.parseInt(MainKeyIndex); //秘钥索引值为 0-5
        byte wKeyIndex = (byte) Integer.parseInt(workKeyIndex);
        if(i < 0 || i >5){
            i = 0;
        }
        final byte mainKeyIndex = i;

        //byte mode = 0; //0x00明文写入  0x81 解密写入  0x01加密写入

        byte finalType = type;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int res = 0;

                deliverResult(callback, Result.START, null, isOnMain);
                byte[] check = new byte[16];
                if(encryptType == 1)
                    check = new byte[8];
                byte[] keyData = ByteTool.hexStr2Bytes(workKey); //工作密钥密文  需要解密的数据
                String mainKey ,mainKeyName;
                if (encryptType == 1){ //3Des
                    mainKeyName = keyInfoUtil.getMainKeyName(mainKeyIndex + 10);
                }else {  //SM4
                    mainKeyName = keyInfoUtil.getMainKeyName(mainKeyIndex);
                }
                mainKey = keyInfoUtil.getKey(mainKeyName);

                if (TextUtils.isEmpty(mainKey)){
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.KEY_NO_MAIN_KEY);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.KEY_NO_MAIN_KEY));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                    return;
                }

                String wKeyStr;
                String workKeyName;
                if (encryptType == 1){  //3DES
                    byte[] wKeyByte = AlgorithmUtil.algorithm3DES(2,ByteTool.hexStr2Bytes(mainKey),keyData);
                    wKeyStr = ByteTool.byte2hex(wKeyByte);
                    workKeyName = keyInfoUtil.getWorkKeyName(keyType,wKeyIndex + 10);
                }else { //SM4
                    byte[] wKeyByte = SMUtil.SM4DecryptECB(keyData,ByteTool.hexStr2Bytes(mainKey));
                    wKeyStr = ByteTool.byte2hex(wKeyByte);
                    workKeyName = keyInfoUtil.getWorkKeyName(keyType,wKeyIndex);
                }
                if (mode == 0){ //todo  mode为0 时 明文写入 不解密 直接写入
                    wKeyStr = workKey;
                }

                keyInfoUtil.saveKey(workKeyName,wKeyStr);

                if (MainActivity.isWakeUp){
                    try {
                        Thread.sleep(2500);
                        LogUtil.e(TAG,"--sleep 2500");
                        MainActivity.isWakeUp = false;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                res = MainActivity.getmMainPci().DLL_PciWriteSKey(finalType, wKeyIndex, (byte)16, keyData, (byte) mode, mainKeyIndex,check);

                LogUtil.e(TAG,"type == " + finalType + "" + " == mainKeyIndex==" + mainKeyIndex + " -- wKeyIndex == " + wKeyIndex + " -- res ==" + res);
                if (res == 0) {
                    Bundle bundle = new Bundle();
                    bundle.putString("data", ByteTool.byte2hex(check));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", res);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.INPUT_WORK_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                }
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);

            }
        };
        keyThreadPool.execute(r);
        return 0;
    }

    /**
     *
     * @param index 索引
     * @param mode 0 加密  1 解密
     * @param encryptType 1 des  2 sm4
     * @param inData 数据
     * @param enMode 0 ECB 1 CBC
     * @param callback
     * @param isOnMain
     */
    public static void calculateData(int index,int mode,int encryptType,String inData,byte enMode,DeviceCallback callback,boolean isOnMain){
        Bundle bundle = new Bundle();
        if (TextUtils.isEmpty(inData) || inData.length() > 4096){
            bundle.putInt(ConstDefine.CODE,-7015);
            bundle.putString(ConstDefine.MESSAGE,"data length error");
            deliverResult(callback,Result.ERROR,bundle,isOnMain);
            return;
        }
        LogUtil.e(TAG,"index == " + index + " enMode  ==== " + enMode + "-----encryptType == " + encryptType);
        byte[] out = new byte[inData.length()/2];
        // SM4 加解密数据
        if (encryptType == 2){
//             enMode = 1; // 0 ECB   1 CBC
            byte iv[] = new byte[16];//"1111111111111111".getBytes();//

            int i =  MainActivity.getmSm().DLL_SMGetDataSM4((byte) index,inData.length()/2,ByteTool.hexStr2Bytes(inData),out,(byte) enMode,(byte) mode,iv,new byte[2]);

            LogUtil.e(TAG,"加解密出来的数据是：" + ByteTool.byte2hex(out));
            if (i == 0) {
                bundle.putString(ConstDefine.data,ByteTool.byte2hex(out));
                deliverResult(callback,Result.SUCCEED,bundle,isOnMain);
            }else {
                bundle.putInt(ConstDefine.CODE,i);
                bundle.putString(ConstDefine.MESSAGE,ErrorDefine.getErrorDescribe(ErrorDefine.SET_ENCRYPT_ERR));
                deliverResult(callback,Result.ERROR,bundle,isOnMain);
            }

        }else if (encryptType == 1){//3DES 加解密

            int i = MainActivity.getmMainPci().DLL_PciGetDes((byte) index,inData.length()/2,ByteTool.hexStr2Bytes(inData),out,(byte) mode); // 3DES
            if (i == 0) {
                LogUtil.e(TAG,"加解密出来的数据是：" + ByteTool.byte2hex(out));
                bundle.putString(ConstDefine.data,ByteTool.byte2hex(out));
                deliverResult(callback,Result.SUCCEED,bundle,isOnMain);
            }else {
                bundle.putInt(ConstDefine.CODE,i);
                bundle.putString(ConstDefine.MESSAGE,ErrorDefine.getErrorDescribe(ErrorDefine.SET_ENCRYPT_ERR));
                deliverResult(callback,Result.ERROR,bundle,isOnMain);
            }
        }
        deliverResult(callback,Result.COMPLETED,new Bundle(),isOnMain);

    }
    /**
     * 检查密钥是否存在
     * @param callback
     * @param isOnMain
     * @return
     */
    public static int checkKeysExist(final DeviceCallback callback,boolean isOnMain){
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int res = -1;
                byte type = 0;
                byte index = 0;
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 0,index);
                LogUtil.e(TAG,"res 0== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 1,index);
                LogUtil.e(TAG,"res 1== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 2,index);
                LogUtil.e(TAG,"res 2== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 3,index);
                LogUtil.e(TAG,"res 3== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 4,index);
                LogUtil.e(TAG,"res 4== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 5,index);
                LogUtil.e(TAG,"res 5== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 6,index);
                LogUtil.e(TAG,"res 6== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 7,index);
                LogUtil.e(TAG,"res 7== " + res);
                res = MainActivity.getmMainPci().DLL_PciCheckKeyExist((byte) 8,index);
                LogUtil.e(TAG,"res 8== " + res);

                if (res == 0) {
                    Bundle bundle = new Bundle();
//                    bundle.putString("data", ByteTool.byte2hex(check));
                    deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.KEYBORAD_CHECK_ERR);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.KEYBORAD_CHECK_ERR));
                    deliverResult(callback, Result.ERROR, bundle, isOnMain);
                }
                deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);

            }
        };
        keyThreadPool.execute(r);
        return 0;
    }
    @Deprecated
    public static void closeKeyBoard() {

        keyBoardModule.PowerOffKeyBoard();
    }
    @Deprecated
    public static boolean initKeyBoard() {
        keyBoardModule.PowerOnKeyBoard();
        return keyBoardModule.isOpen();

    }


    /***********************************密码键盘结束**************************************/


    /********************************金融板*****************************************/
    @Deprecated
    public static int testPsamSlot(final byte slot) {
        byte[] ATD = new byte[100];
        int ret = -1;
        try {
            ret = financialModule.libIccOpen(slot, (byte) 0x01, ATD);
            if (ret != 0) {
                Log.e("Icc_Open", ret + "!!");
                return ret;
            } else {
                return ret;
            }
//            byte sendData[] = new byte[530];
//            byte cmd[] = new byte[4];
//            cmd[0] = 0x00; // 0-3 cmd
//            cmd[1] = (byte) 0xa4;
//            cmd[2] = 0x04;
//            cmd[3] = 0x00;
//            short Lc = 0x0e;
//            short Le = 256;
//            byte[] dataIn = new byte[512];
//            // 02 B7 07 00 14 00 00 A4 04 00 00 0E 31 50 41 59 2E 53 59 53 2E 44 44
//            // 46 30 B4 82
//            String sendmsg = "1PAY.SYS.DDF01";
//            sendData = sendmsg.getBytes();
//            System.arraycopy(sendData, 0, dataIn, 0, sendData.length);
//            APDU_SEND ApduSend = new APDU_SEND(cmd, Lc, dataIn, Le);
//            APDU_RESP ApduResp = new APDU_RESP();
//            ret = financialModule.Icc_Command(slot, ApduSend, ApduResp);
//            Log.e("testPsamSlot[ run ]", "Command ret = " + ret);
        } finally {
            financialModule.libIccClose(slot);
        }


    }

    /**
     * 升级金融板固件
     *
     * @param fileName
     * @param callback
     * @param isOnMain
     */
    public static void updateFw(String fileName, final DeviceCallback callback, boolean isOnMain) {
        FwUpdateModule module = new FwUpdateModule();
        try {
            module.readFile(fileName);
            module.beginDownLoad(callback);
            Thread.sleep(1000);
            module.mcuReset();

        } catch (IOException e) {

            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        module.setCallback(callback, isOnMain);
//        module.startDownload();
    }
// todo ------ 银行卡 -----------------------------------------------------------------------------------------------------
    //上电
    public static int icCardPowerOn(final DeviceCallback callback,EmvOptions options,final int timeOutMs,final boolean isOnMain){
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.IC_POWER_ON,options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }
    //下电
    public static int icCardPowerOff(final DeviceCallback callback,EmvOptions options,final int timeOutMs,final boolean isOnMain){
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.IC_POWER_OFF,options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }
    //apdu
    public static int icCardApdu(final DeviceCallback callback,String apduSend,final int timeOutMs,final boolean isOnMain){
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.IC_APDU,ConstDefine.AUTO_CARD,
                apduSend,"", callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 自动获取card
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int autoCardInfo(final DeviceCallback callback, EmvOptions options, String[] wantTags, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.AUTO_READ_CARD_INFO, options, callback, wantTags, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }
    /**
     * 自动检测获取卡类型 磁条卡时 返回读取数据
     * 接触和非接直接返回（不读卡）
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int autoCardCheckCard(final DeviceCallback callback, EmvOptions options, String[] wantTags, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.AUTO_READ_CHECK_CARD, options, callback, wantTags, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }
    /**
     * ARPC校验
     *
     * @param ICType
     * @param ARPC
     * @param ScriptStr
     * @param
     * @return
     */
    public static int ARPCExecuteScript(int ICType, String ARPC, String ScriptStr, final DeviceCallback callback, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.ARPCANDSCRIPT,ICType, ARPC, ScriptStr, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;

    }

    /**
     * 自动模式读取明细
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readLoadLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.AUTO_READ_LOAD, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 自动模式读取交易记录
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int autoReadLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.AUTO_READ_LOG, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 非接模式读取明细
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readPicLoadLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_PIC_LOAD, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 接触读取交易明细
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readIcLoadLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_IC_LOAD, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 非接模式读取明细
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readPicLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_PIC_LOG, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 接触读取交易明细
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readIcLog(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_IC_LOG, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 非接读取标签
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readPiccInfo(final DeviceCallback callback, EmvOptions options, final String[] wantTags, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_PIC_INFO, options, callback, wantTags, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /** 读IC卡 信息
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readIcInfo(final DeviceCallback callback, EmvOptions options, final String[] wantTags, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_IC_INFO, options, callback, wantTags, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 读社保卡
     * @param callback
     * @param timeOutMs
     * @param isOnMain
     * @return
     */
    public static int readSocialCard(final DeviceCallback callback,  final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_SOCIAL_CARD, 0,"", callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }
    public static void cancelFinancial() {
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
    }

    /**
     * 刷磁条卡
     *
     * @param callback
     * @param timeOutMs
     * @return
     */
    public static int readMsr(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_MSR, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;
    }

    /**
     * 单独获取卡号
     *
     * @param callback
     * @param timeOutMs
     * @param isOnMain
     * @return
     */
    public static int autoCardNo(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.AUTO_READ_CARD_NO, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;

    }

    public static int readPiccCardNo(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_PIC_CARD_NO, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;

    }

    public static int readIcCardNo(final DeviceCallback callback, EmvOptions options, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (financialRunnable != null) {
            financialRunnable.stopRun();
            financialRunnable = null;
        }
        financialRunnable = new FinancialRunnable(FinancialRunnable.Action.READ_IC_CARD_NO, options, callback, timeOutMs, isOnMain);
        finanThreadPool.execute(financialRunnable);
        return 0;

    }

    /**
     * 金融板上电,需要时间回调
     *
     * @param callback
     * @param isOnMain
     * @return
     */
    @Deprecated
    public static int openFinancial(final DeviceCallback callback, final boolean isOnMain) {

        boolean isOn = financialModule.init();
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    int res = -1;
                    Timer tm = new Timer(15000);
                    tm.start();
                    deliverResult(callback, Result.START, null, isOnMain);
                    while (true) {
                        if (tm.timeOut()) {
                            Log.e(TAG, "tm.timeOut!!");
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.TIME_OUT);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.TIME_OUT));
                            deliverResult(callback, Result.ERROR, bundle, isOnMain);
                            break;
                        }
                        byte[] bootVer = new byte[3];
                        byte[] appVer = new byte[3];
                        res = financialModule.readVersion(bootVer, appVer);
                        Log.e(TAG, "res:" + res);
                        if (res == 0) {
                            if (financialModule.EmvLib_Init() != 0) {
                                Bundle bundle = new Bundle();
                                bundle.putInt("code", ErrorDefine.EMV_INIT_ERR);
                                bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.EMV_INIT_ERR));
                                deliverResult(callback, Result.ERROR, bundle, isOnMain);
                                break;
                            }
                            Bundle bundle = new Bundle();
                            bundle.putByteArray("data", appVer);
                            deliverResult(callback, Result.SUCCEED, bundle, isOnMain);
                            break;
                        }
                        financialModule.flush();
                        SystemClock.sleep(10);
                    }
                    deliverResult(callback, Result.COMPLETED, new Bundle(), isOnMain);
                    Log.e(TAG, "COMPLETED");
                }
            }
        };
        finanThreadPool.execute(r);
        return isOn ? 0 : -1;
    }
    @Deprecated
    public static boolean closeFinancial() {

        return financialModule.PowerOff();
    }


    /********************************金融模块结束*****************************************/


    /************************************
     * 身份证模块
     *************************************/

    public static int readIdentity(final DeviceCallback callback, final int timeOutMs, final boolean isOnMain) {
        if (callback == null)
            return ErrorDefine.NO_CALLBACK;
        if (identityRunnable != null) {
            identityRunnable.stopRun();
            identityRunnable = null;
        }
        identityRunnable = new IdentityRunnable(false, callback, timeOutMs, isOnMain);
        idThreadPool.submit(identityRunnable);
        return 0;
    }

    @Deprecated
    public static void closeIdentity() {
        identityModule.ReleaseReader();
        identityModule.PowerOffReader();

    }

//    public static boolean initIdentity() {
//        identityModule.PowerOnReader();
//        return identityModule.init();
//    }

    /**
     * 读取身份证模块编号
     *
     * @return
     */
    @Deprecated
    public static String readIdSerialNo() {
        String[] sRet = new String[1];
        byte[] sam = identityModule.ReadSAMIDBuf(sRet);
        return ByteTool.byte2hex(sam);
    }

    public static void cancelIdentity() {
        if (identityRunnable != null) {
            identityRunnable.stopRun();
            identityRunnable = null;
        }

    }


    /************************************
     * 身份证模块结束
     *************************************/


    protected static synchronized void deliverResult(final DeviceCallback callback, Result result, Bundle bundle, boolean onMainThread) {
        if (onMainThread) {
            handler.setCallback(callback);
            if (result == Result.SUCCEED) {
                Message msg = new Message();
                msg.what = SUCCESS;
                msg.setData(bundle);
                handler.sendMessage(msg);
            } else if (result == Result.ERROR) {
                Message msg = new Message();
                msg.what = ERROR;
                msg.setData(bundle);
                handler.sendMessage(msg);
            } else if (result == Result.COMPLETED) {
                Message msg = new Message();
                msg.what = COMPLETED;
                msg.setData(bundle);
                handler.sendMessage(msg);
            } else if (result == Result.START) {
                Message msg = new Message();
                msg.what = START;
                handler.sendMessage(msg);
            }
        } else {
            if (result == Result.SUCCEED) {
                callback.onSuccess(bundle);
            } else if (result == Result.ERROR) {
                callback.onError(bundle);
            } else if (result == Result.COMPLETED) {
                callback.onCompleted(bundle);
            } else if (result == Result.START) {
                callback.onStart();
            }
        }

    }

    private static class CallBackHandler extends Handler {
        private DeviceCallback callback;

        public CallBackHandler() {

            super(Looper.getMainLooper());
        }

        public void setCallback(DeviceCallback callback) {
            this.callback = callback;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case START: {
                    callback.onStart();
                    break;
                }
                case SUCCESS: {
                    Bundle bundle = msg.getData();
                    callback.onSuccess(bundle);
                    break;
                }
                case ERROR: {
                    Bundle bundle = msg.getData();
                    callback.onError(bundle);
                    break;
                }
                case COMPLETED: {
                    Bundle bundle = msg.getData();
                    callback.onCompleted(bundle);
                    break;
                }
            }

        }

    }

    public static void showUpdateMsg(String msg){
        handler.post(new Runnable() {
            @Override
            public void run() {
                MyToast.show(MainActivity.context,msg,Toast.LENGTH_SHORT);
            }
        });
    }

    public static void showToast(String message) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.context, message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private static boolean tryOpenMAC(WifiManager manager) {
        boolean softOpenWifi = false;
        int state = manager.getWifiState();
        if (state != WifiManager.WIFI_STATE_ENABLED && state != WifiManager.WIFI_STATE_ENABLING) {
            manager.setWifiEnabled(true);
            softOpenWifi = true;
        }
        return softOpenWifi;
    }

    //尝试关闭MAC
    private static void tryCloseMAC(WifiManager manager) {
        manager.setWifiEnabled(false);
    }

    //尝试获取MAC地址
    private static String tryGetMAC(WifiManager manager) {
        WifiInfo wifiInfo = manager.getConnectionInfo();
        if (wifiInfo == null || wifiInfo.getMacAddress() == null) {
            return null;
        }
        String mac = wifiInfo.getMacAddress().replaceAll(":", "").trim().toUpperCase();
        LogUtil.e(TAG,"tryGetMAC=" + mac);
        return mac;
    }

    //尝试读取MAC地址
    @Deprecated
    public static String getMacFromDevice() {
        String mac = null;
        WifiManager wifiManager = (WifiManager) MainActivity.context.getSystemService(Context.WIFI_SERVICE);
        mac = tryGetMAC(wifiManager);
        LogUtil.e(TAG,"第一次获取Mac=" + mac);

        if (mac != null) {
            return mac;
        }

        //获取失败，尝试打开wifi获取
        boolean isOkWifi = false;
        for (int i = 0; i < 3; i++) {
            isOkWifi = tryOpenMAC(wifiManager);
            if (isOkWifi) {
                break;
            }
            SystemClock.sleep(100);
        }


        for (int index = 0; index < 10; index++) {
            //如果第一次没有成功，第二次做100毫秒的延迟。
            if (index != 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            mac = tryGetMAC(wifiManager);
            LogUtil.e(TAG,"第二次获取Mac=" + mac);
            if (mac != null) {
                break;
            }
        }

        //尝试关闭wifi
        if (isOkWifi) {
            tryCloseMAC(wifiManager);
        }
        return mac;
    }

}
